/**
 * Copyright (c) 2015 https://github.com/howiefh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.tyijian.admin.shiro.credentials;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.auth0.jwt.JWTVerifier;
import com.tyijian.admin.entity.SysUser;
import com.tyijian.admin.service.UserService;
import com.tyijian.admin.shiro.token.JsonWebToken;

/**
 * 
 * 
 * @author yangjp
 */
public class JsonWebTokenCredentialsMatcher implements CredentialsMatcher {
	
	private static final Logger logger = LoggerFactory.getLogger(JsonWebTokenCredentialsMatcher.class);

	@Autowired
	private UserService userService;

	private String audience;
	private String secret;

	public String getAudience() {
		return audience;
	}

	public void setAudience(String audience) {
		this.audience = audience;
	}

	public String getSecret() {
		return secret;
	}

	public void setSecret(String secret) {
		this.secret = secret;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.apache.shiro.authc.credential.CredentialsMatcher#doCredentialsMatch
	 * (org.apache.shiro.authc.AuthenticationToken,
	 * org.apache.shiro.authc.AuthenticationInfo)
	 */
	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

		JsonWebToken jsonWebToken = (JsonWebToken) token;
		JWTVerifier verifier = new JWTVerifier(secret, audience);
		if (jsonWebToken == null || StringUtils.isBlank(jsonWebToken.getToken())) {
			return false;
		}
		Map<String, Object> map;
		try {
			map = verifier.verify(jsonWebToken.getToken());
			String loginName = (String) map.get("loginName");// 获取jwt的信息
			SysUser user = userService.getUserFromCache("UserCache:" + loginName);
			if (!jsonWebToken.getToken().equals(user.getToken())) { // 比对是否最新的token
				return false;
			}

			SimpleAuthenticationInfo authenticationInfo = (SimpleAuthenticationInfo) info;
			String realmName = authenticationInfo.getPrincipals().getRealmNames().iterator().next();
			SimplePrincipalCollection principals = new SimplePrincipalCollection();
			principals.add(user.getId(), realmName);
			authenticationInfo.setPrincipals(principals);
			return true;
		} catch (Exception e) {
			logger.error(e.getMessage());
			return false;
		} 
	}
}
